home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2008 April / PCgo 2008-04 (DVD).iso / interface / contents / demoversionen_3846 / 13664 / files / Data1.cab / autorect.cpp1 < prev    next >
Encoding:
Text File  |  2001-09-22  |  20.6 KB  |  876 lines

  1. /******************************************************************/
  2. /*                                                                */
  3. /*                      TurboCAD for Windows                      */
  4. /*                   Copyright (c) 1993 - 2001                    */
  5. /*             International Microcomputer Software, Inc.         */
  6. /*                            (IMSI)                              */
  7. /*                      All rights reserved.                      */
  8. /*                                                                */
  9. /******************************************************************/
  10.  
  11. // AutoRect.cpp : Implementation of CAutoRect
  12. #include "stdafx.h"
  13. #include "RRectA.h"
  14. #include "AutoRect.h"
  15. #include "RectPage.h"  // Property page class
  16. #include "Imsigx.h"   // TurboCAD interfaces
  17. #include <math.h>
  18.  
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Standard variants
  22. COleVariant t(-1L, VT_BOOL);
  23. COleVariant f(0L, VT_BOOL);
  24. COleVariant z(0.0);
  25. COleVariant missing((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  26. const double PI = 3.14159265;
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CAutoRect
  30.  
  31. const IID IID_IGraphic = 
  32.     {0x6A481109,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
  33. static const IID IID_ISmartObjectServer =
  34. {0x6A481303,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
  35.  
  36.  
  37. STDMETHODIMP CAutoRect::get_ClassID(BSTR *pVal)
  38. {
  39.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  40.  
  41.     HRESULT hRes = E_FAIL;
  42.     LPOLESTR olestr = NULL;
  43.     try
  44.     {
  45.         if(SUCCEEDED( ::StringFromCLSID(CLSID_AutoRect, &olestr)))
  46.         {
  47.  
  48.             *pVal = ::SysAllocString(olestr);
  49.             hRes = S_OK;
  50.         }
  51.     }
  52.     catch (...)
  53.     {
  54.  
  55.     }
  56.  
  57.     if (olestr != NULL)
  58.     CoTaskMemFree(olestr);
  59.  
  60.     return hRes;
  61. }
  62.  
  63.  
  64. STDMETHODIMP CAutoRect::get_Description(BSTR *pVal)
  65. {
  66.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  67.  
  68.     HRESULT hRes = E_FAIL;
  69.     // Get the description from the resource
  70.     CString strResult;
  71.     if (strResult.LoadString(IDS_AUTORECT_DESCRIPTION))
  72.     {
  73.         hRes = S_OK;
  74.         *pVal = strResult.AllocSysString();
  75.     }
  76.     return hRes;
  77.  
  78.  
  79. }
  80.  
  81. const long VT_INTEGER_ENUM = VT_I2 + 100;
  82. const long VT_LONG_ENUM = VT_I4 + 100;
  83. const long VT_STRING_ENUM = VT_BSTR + 100;
  84.  
  85. const long GF_COSMETIC = 128;
  86.  
  87. enum StockPages {
  88.     PP_STOCK_PEN = 1,
  89.     PP_STOCK_BRUSH = 2,
  90.     PP_STOCK_TEXT = 4,
  91.     PP_STOCK_INSERT = 8,
  92.     PP_STOCK_VIEWPORT = 16,
  93.     PP_STOCK_AUTO = 32
  94. };
  95.  
  96. // our Rounded rectangle object has only one property called Roundess
  97. const long nProperties = 1;
  98. // define one property
  99. enum PropertyIDs 
  100. {
  101.    idRoundness = 1,
  102. };
  103.  
  104.  
  105.  
  106. STDMETHODIMP CAutoRect::GetPropertyInfo(VARIANT *Names, VARIANT *Types, VARIANT *IDs, VARIANT *Defaults, long* ret)
  107. {
  108.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  109.     HRESULT hRes = E_FAIL;
  110.  
  111.      ASSERT(Names->vt == (VT_ARRAY|VT_BSTR));
  112.     ASSERT(Types->vt == (VT_ARRAY|VT_I4));
  113.     ASSERT(IDs->vt == (VT_ARRAY|VT_I4));
  114.     ASSERT(Defaults->vt == (VT_ARRAY|VT_VARIANT));
  115.  
  116.      SAFEARRAYBOUND bound = { nProperties, 0 };
  117.     try
  118.     {
  119.         if (FAILED(::SafeArrayRedim(Names->parray, &bound)))
  120.         {
  121.             *ret = 0;
  122.             return hRes;
  123.         }
  124.         if (FAILED(::SafeArrayRedim(Types->parray, &bound)))
  125.         {
  126.             *ret = 0;
  127.             return hRes;
  128.         }
  129.         if (FAILED(::SafeArrayRedim(IDs->parray, &bound)))
  130.         {
  131.             *ret = 0;
  132.             return hRes;
  133.         }
  134.         if (FAILED(::SafeArrayRedim(Defaults->parray, &bound)))
  135.         {
  136.             *ret = 0;
  137.             return hRes;
  138.         }
  139.  
  140.         BSTR* rgNames;
  141.         long* rgTypes;
  142.         long* rgIDs;
  143.         VARIANT* rgDefaults; 
  144.         *ret = 0;
  145.         if (SUCCEEDED(::SafeArrayAccessData(Names->parray, (void**)&rgNames)))
  146.         {
  147.             if (SUCCEEDED(::SafeArrayAccessData(Types->parray, (void**)&rgTypes)))
  148.             {
  149.                 if (SUCCEEDED(::SafeArrayAccessData(IDs->parray, (void**)&rgIDs)))
  150.                 {
  151.                     if (SUCCEEDED(::SafeArrayAccessData(Defaults->parray, (void**)&rgDefaults)))
  152.                     {
  153. //                        rgNames[0] = ::SysAllocString(OLESTR("Roundness"));
  154.                         CString strStr;
  155.                         strStr.LoadString(IDS_PROPERTYROUNDESS);
  156.                         rgNames[0] = ::SysAllocString(strStr.AllocSysString());
  157.  
  158.                         rgTypes[0] = VT_R8;
  159.                         rgIDs[0] = idRoundness;
  160.                         rgDefaults[0].vt = VT_R8;
  161.                         rgDefaults[0].dblVal = 50.0;
  162.  
  163.                         hRes = ::SafeArrayUnaccessData(Defaults->parray);
  164.                         CHECK_HRESULT(hRes)
  165.  
  166.                         *ret = nProperties;
  167.                     }
  168.                     hRes = ::SafeArrayUnaccessData(IDs->parray);
  169.                     CHECK_HRESULT(hRes)
  170.                 }
  171.                 hRes = ::SafeArrayUnaccessData(Types->parray);
  172.                 CHECK_HRESULT(hRes)
  173.             }
  174.             hRes = ::SafeArrayUnaccessData(Names->parray);
  175.             CHECK_HRESULT(hRes)
  176.         }
  177.     }
  178.     catch (...)
  179.     {
  180.         TRACE_EXCEPTION("CAutoRect::GetPropertyInfo")
  181.     }
  182.     
  183.     return hRes;
  184.  
  185. }
  186.  
  187. STDMETHODIMP CAutoRect::GetPageInfo(IDispatch *AGraphic, long *StockPages, VARIANT *Names,long* ret)
  188. {
  189.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  190.     HRESULT hRes = E_FAIL;
  191.  
  192.     ASSERT(StockPages != NULL);
  193.      ASSERT(Names->vt == (VT_ARRAY|VT_BSTR));
  194.  
  195.     // Request pen page and auto page
  196.     *StockPages = PP_STOCK_PEN | PP_STOCK_AUTO;
  197.  
  198.      SAFEARRAYBOUND bound = { 1, 0 };
  199.     if (FAILED(::SafeArrayRedim(Names->parray, &bound)))
  200.     {
  201.         *ret = 0;
  202.         return hRes;
  203.     }
  204.  
  205.     CString strCaption;
  206.     strCaption.LoadString(IDS_AUTORECT_CAPTION);
  207.     BSTR bstrCaption = strCaption.AllocSysString();
  208.  
  209.     long lIndex = 0;
  210.     if (FAILED(SafeArrayPutElement(Names->parray, &lIndex, (void*)bstrCaption)))
  211.     {
  212.         ::SysFreeString(bstrCaption);
  213.         *ret = 0;
  214.         return hRes;
  215.     }
  216.     *ret = 1;
  217.     hRes = S_OK;
  218.     return hRes;
  219.  
  220. }
  221.  
  222. STDMETHODIMP CAutoRect::GetWizardInfo(VARIANT *Names,long* ret)
  223. {
  224.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  225.     HRESULT hRes = S_OK;
  226.     // No wizards, nothing to do
  227.  
  228.     *ret = 0;
  229.     return hRes;
  230.  
  231. }
  232.  
  233. STDMETHODIMP CAutoRect::GetEnumNames(long PropID, VARIANT *Names, VARIANT *Values,long* ret)
  234. {
  235.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  236.     HRESULT hRes = S_OK;
  237.  
  238.     // TODO: Add your implementation code here
  239.     // Should never be called!
  240.     *ret = 0;
  241.     return hRes;
  242. }
  243.  
  244. STDMETHODIMP CAutoRect::PageControls(IDispatch *ThisRegenMethod, IDispatch *AGraphic, long PageNumber, boolean SaveProperties, VARIANT_BOOL* ret)
  245. {
  246.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  247.     HRESULT hRes = E_FAIL;
  248.  
  249.     IGraphic* pIGraphic = NULL;
  250.     if (FAILED(AGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic)))
  251.     {
  252.         *ret = FALSE;
  253.         return hRes;
  254.     }
  255.  
  256.     *ret = FALSE;
  257.     Properties* pProps = NULL;
  258.     Property* pProp = NULL;
  259.     COleVariant varIndex, varValue;
  260.     try
  261.     {
  262.         if (SUCCEEDED(pIGraphic->get_Properties(&pProps)))
  263.         {
  264.             if (SaveProperties)
  265.             {
  266.                 if (m_pRectPage != NULL)
  267.                 {
  268.                     // Note: the following can fail (for non-rounded rect graphics)
  269.                     CString strStr;
  270.                     strStr.LoadString(IDS_PROPERTYROUNDESS);
  271.                     varIndex = LPCTSTR(strStr);
  272.                     if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  273.                     {
  274.                         varValue = (const long)m_pRectPage->m_roundness;
  275.                         hRes = pProp->put_Value(0, &varValue);
  276.                         CHECK_HRESULT(hRes)
  277.  
  278.                         pProp->Release();
  279.                         varValue.Clear();
  280.                     }
  281.                     *ret = TRUE;
  282.                 }
  283.             }
  284.             else
  285.             {
  286.                 ASSERT(m_pRectPage == NULL);
  287.                 m_pRectPage = new CRectPage();
  288.  
  289.                 // Note: the following can fail (for indeterminate values)
  290.                 CString strStr;
  291.                 strStr.LoadString(IDS_PROPERTYROUNDESS);
  292.                 varIndex = LPCTSTR(strStr);
  293.                 if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  294.                 {
  295.                     if (SUCCEEDED(pProp->get_Value(0, &varValue)) &&
  296.                         varValue.vt == VT_R8)
  297.                         m_pRectPage->m_roundness = varValue.dblVal;
  298.                     pProp->Release();
  299.                     varValue.Clear();
  300.                 }
  301.                 hRes = S_OK;
  302.                 *ret = TRUE;
  303.             }
  304.             pProps->Release();
  305.         }
  306.  
  307.         pIGraphic->Release();
  308.     }
  309.     catch (...)
  310.     {
  311.         TRACE_EXCEPTION("CAutoRect::PageControls")
  312.     }
  313.  
  314.     return hRes;
  315.  
  316.  
  317.  
  318. }
  319.  
  320. STDMETHODIMP CAutoRect::PageDone(IDispatch *ThisRegenMethod, VARIANT *PageNumber)
  321. {
  322.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  323.  
  324.     delete m_pRectPage;
  325.     m_pRectPage = NULL;
  326.     HRESULT hRes = S_OK;
  327.     return hRes;
  328.  
  329. }
  330.  
  331. STDMETHODIMP CAutoRect::PropertyPages(IDispatch *ThisRegenMethod, VARIANT *PageNumber, VARIANT_BOOL* ret)
  332. {
  333.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  334.     HRESULT hRes = E_FAIL;
  335.  
  336.     if (m_pRectPage == NULL)
  337.     {
  338.         *ret = FALSE;
  339.         return hRes;
  340.     }
  341.     // Run the dialog and get the results
  342.     int nResult = m_pRectPage->DoModal();
  343.     *ret = TRUE;
  344.     hRes = S_OK;
  345.  
  346.     return hRes;
  347. }
  348.  
  349. STDMETHODIMP CAutoRect::Wizard(IDispatch *ThisRegenMethod, VARIANT *WizardNumber, VARIANT_BOOL* ret)
  350. {
  351.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  352.     HRESULT hRes = E_FAIL;
  353.  
  354.     // No wizards, so just return FALSE.
  355.     *ret = FALSE;
  356.     return hRes;
  357. }
  358.  
  359. STDMETHODIMP CAutoRect::OnGeometryChanged(IDispatch *AGraphic, long GeomID, VARIANT *ParamOld, VARIANT *ParamNew)
  360. {
  361.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  362.     HRESULT hRes = S_OK;
  363.     // OK to change our geometry, so just return TRUE.
  364.     return hRes;
  365. }
  366.  
  367. STDMETHODIMP CAutoRect::OnGeometryChanging(IDispatch *AGraphic, long GeomID, VARIANT *ParamOld, VARIANT *ParamNew, VARIANT_BOOL* ret)
  368. {
  369.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  370.  
  371.     // TODO: Add your implementation code here
  372.     HRESULT hRes = S_OK;
  373.     *ret = TRUE;
  374.     return hRes;
  375. }
  376.  
  377.  
  378. double GetRoundness(IGraphic* pIGraphic)
  379. {
  380.     double roundness = 50.0;
  381.     Properties* pProps = NULL;
  382.     Property* pProp = NULL;
  383.     COleVariant varIndex, varValue;
  384.     if (SUCCEEDED(pIGraphic->get_Properties(&pProps)))
  385.     {
  386.         CString strStr;
  387.         strStr.LoadString(IDS_PROPERTYROUNDESS);
  388.         varIndex = LPCTSTR(strStr);
  389.         if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  390.         {
  391.             if (SUCCEEDED(pProp->get_Value(0, &varValue)) &&
  392.                 varValue.vt == VT_R8)
  393.             {
  394.                 roundness = varValue.dblVal;
  395.             }
  396.             pProp->Release();
  397.         }
  398.         pProps->Release();
  399.     }
  400.     return roundness;
  401. }
  402.  
  403. void SetRoundness(IGraphic* pIGraphic, double roundness)
  404. {
  405.     Properties* pProps = NULL;
  406.     Property* pProp = NULL;
  407.     COleVariant varIndex;
  408.     if (SUCCEEDED(pIGraphic->get_Properties(&pProps)))
  409.     {
  410.         CString strStr;
  411.         strStr.LoadString(IDS_PROPERTYROUNDESS);
  412.         varIndex = LPCTSTR(strStr);
  413.         if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  414.         {
  415.             COleVariant varValue;
  416.             varValue.vt = VT_R8;
  417.             varValue.dblVal = roundness;
  418.             pProp->put_Value(0, &varValue);
  419.             pProp->Release();
  420.         }
  421.         pProps->Release();
  422.     }
  423. }
  424.  
  425.  
  426.  
  427. BOOL GetVertexXYZ(IGraphic* pIGraphic, const long lVertex, double& x, double& y, double& z)
  428. {
  429.     IVertex* pIVertex = NULL;
  430.     Vertices* pVerts = NULL;
  431.     BOOL bSuccess = FALSE;
  432.     if (SUCCEEDED(pIGraphic->get_Vertices(&pVerts)))
  433.     {
  434.         COleVariant varIndex = lVertex;
  435.         if (SUCCEEDED(pVerts->get_Item(&varIndex, &pIVertex)))
  436.         {
  437.             if (SUCCEEDED(pIVertex->get_X(&x)) &&
  438.                 SUCCEEDED(pIVertex->get_Y(&y)) &&
  439.                 SUCCEEDED(pIVertex->get_Z(&z)))
  440.                 bSuccess = TRUE;
  441.             pIVertex->Release();
  442.         }
  443.         pVerts->Release();
  444.     }
  445.     return bSuccess;
  446. }
  447.  
  448. void AddLineChild(Graphics* pGraphics, double x0, double y0, double x1, double y1)
  449. {
  450.     HRESULT hRes = E_FAIL;
  451.     IGraphic* pChild = NULL;
  452.     COleVariant x, y;
  453.     Vertices* pVerts = NULL;
  454.     IVertex* pIVertex = NULL;
  455.     
  456.     try
  457.     {
  458.         hRes = pGraphics->Add(&missing /*GraphicType*/,
  459.                               &missing /*RegenMethod*/,
  460.                               &t /*Inherit*/, 
  461.                               &missing /*Style*/,
  462.                               &missing /*Before*/,
  463.                               &missing /*After*/,                    
  464.                               &pChild);
  465.         CHECK_HRESULT(hRes)
  466.     
  467.         hRes = pChild->put_Cosmetic(TRUE);
  468.         CHECK_HRESULT(hRes)
  469.  
  470.  
  471.         hRes = pChild->get_Vertices(&pVerts);
  472.         CHECK_HRESULT(hRes)
  473.         
  474.         x = x0;
  475.         y = y0;
  476.         hRes = pVerts->Add(&x, &y, &z,
  477.                            &f /*penDown*/, 
  478.                            &t /*selectable*/,
  479.                            &t /*snappable*/,
  480.                            &t /*editable*/, 
  481.                            &t /*linkable*/,
  482.                            &f /*calculated*/,
  483.                            &missing /*before*/,
  484.                            &missing /*after*/,
  485.                            &pIVertex);
  486.         CHECK_HRESULT(hRes)
  487.  
  488.         pIVertex->Release();
  489.         x = x1;
  490.         y = y1;
  491.         hRes = pVerts->Add(&x, &y, &z,
  492.                            &t /*penDown*/, 
  493.                            &t /*selectable*/,
  494.                            &t /*snappable*/,
  495.                            &t /*editable*/, 
  496.                            &t /*linkable*/,
  497.                            &f /*calculated*/,
  498.                            &missing /*before*/,
  499.                            &missing /*after*/,
  500.                            &pIVertex);
  501.         CHECK_HRESULT(hRes)
  502.  
  503.         
  504.         
  505.     }
  506.  
  507.     catch (...)
  508.     {
  509.         TRACE_EXCEPTION("AddLineChild")
  510.     }
  511.  
  512.     if (pIVertex != NULL)
  513.         pIVertex->Release();
  514.     
  515.     if(pVerts != NULL)
  516.         pVerts->Release();
  517.     
  518.     if (pChild != NULL)
  519.         pChild->Release();
  520. }
  521.  
  522. void AddArcChild(Graphics* pGraphics, double xc, double yc, double r, double start, double end)
  523. {
  524.     HRESULT hRes = E_FAIL;
  525.     IGraphic* pChild = NULL;
  526.     COleVariant type((long)imsiArc);
  527.     try 
  528.     {
  529.     
  530.         hRes = pGraphics->Add(&type /*GraphicType*/,
  531.                                  &missing /*RegenMethod*/,
  532.                               &t /*Inherit*/, 
  533.                               &missing /*Style*/,
  534.                               &missing /*Before*/,
  535.                               &missing /*After*/,                    
  536.                               &pChild);
  537.         CHECK_HRESULT(hRes)
  538.  
  539.         
  540.         hRes = pChild->put_Cosmetic(TRUE);
  541.         CHECK_HRESULT(hRes)
  542.  
  543.         
  544.         COleVariant x(xc);
  545.         COleVariant y(yc);
  546.         COleVariant rad(r);
  547.         COleVariant sa(start);
  548.         COleVariant ea(end);
  549.  
  550.         hRes = pChild->ArcSet(&x, &y, &z, &rad, &missing, &sa, &ea, &missing);
  551.         CHECK_HRESULT(hRes)
  552.         
  553.     }
  554.  
  555.     catch (...)
  556.     {
  557.         TRACE_EXCEPTION("AddArcChild")
  558.     }
  559.  
  560.     if(pChild != NULL)
  561.     pChild->Release();
  562. }
  563.  
  564.  
  565.  
  566.  
  567. STDMETHODIMP CAutoRect::OnNewGraphic(IDispatch *CopyGraphic, boolean Copy, VARIANT_BOOL* ret)
  568. {
  569.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  570.     HRESULT hRes = E_FAIL;
  571.  
  572.     // TODO: Add your implementation code here
  573.  
  574.     // Return FALSE on failure.
  575.     // For copies, usually do nothing.
  576.     if (Copy)
  577.     {
  578.         *ret = TRUE;
  579.         hRes = S_OK;
  580.         return hRes;
  581.     
  582.     }
  583.     // Add vertices, etc. for new graphic here.
  584.  
  585.     // TODO: Do nothing here.
  586.     *ret = TRUE;
  587.     try
  588.     {
  589.         IGraphic* pIGraphic = NULL;
  590.         hRes = CopyGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic);
  591.         CHECK_HRESULT(hRes)
  592.  
  593.  
  594.         Vertices* pVerts = NULL;
  595.         IVertex* pIVertex = NULL;
  596.         if (SUCCEEDED(pIGraphic->get_Vertices(&pVerts)))
  597.         {
  598.             COleVariant x;
  599.             COleVariant y;
  600.  
  601.             // First 2 vertices are lower left and upper right corners.
  602.             const double corners[2*2] = { -1.0, -0.5, 1.0, 0.5 };
  603.             for (int i = 0; i < 2*2; )
  604.             {
  605.                 x = corners[i++];
  606.                 y = corners[i++];
  607.  
  608.                 if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  609.                     &f /*penDown*/, 
  610.                     &t /*selectable*/,
  611.                     &f /*snappable*/,
  612.                     &f /*editable*/, 
  613.                     &f /*linkable*/,
  614.                     &f /*calculated*/,
  615.                     &missing /*before*/,
  616.                     &missing /*after*/,
  617.                     &pIVertex)))
  618.                     pIVertex->Release();
  619.             }
  620.  
  621.             // Third vertex is rounding handle (calculated)
  622.             double r = 0.5 * GetRoundness(pIGraphic) / 100.0;
  623.             double offset = 0.1 * r;
  624.             x = 1.0 - r;
  625.             y = 0.5 + offset;
  626.             if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  627.                 &f /*penDown*/, 
  628.                 &f /*selectable*/,
  629.                 &f /*snappable*/,
  630.                 &f /*editable*/, 
  631.                 &f /*linkable*/,
  632.                 &f /*calculated*/,
  633.                 &missing /*before*/,
  634.                 &missing /*after*/,
  635.                 &pIVertex)))
  636.                 pIVertex->Release();
  637.  
  638.             // Fourth vertex is rounding handle (editable)
  639.             if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  640.                 &f /*penDown*/, 
  641.                 &t /*selectable*/,
  642.                 &f /*snappable*/,
  643.                 &t /*editable*/, 
  644.                 &f /*linkable*/,
  645.                 &f /*calculated*/,
  646.                 &missing /*before*/,
  647.                 &missing /*after*/,
  648.                 &pIVertex)))
  649.                 pIVertex->Release();
  650.  
  651.             pIGraphic->Release();
  652.         }
  653.     }
  654.     catch (...)
  655.     {
  656.         TRACE_EXCEPTION("CAutoRect::OnNewGraphic")
  657.         *ret = FALSE;
  658.     }
  659.  
  660.     return hRes;
  661. }
  662.  
  663. STDMETHODIMP CAutoRect::OnCopyGraphic(IDispatch *CopyGraphic, IDispatch *SourceGraphic, VARIANT_BOOL* ret)
  664. {
  665.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  666.     HRESULT hRes = S_OK;
  667.     // TODO: Add your implementation code here
  668.     *ret = TRUE;
  669.     return hRes;
  670. }
  671.  
  672. STDMETHODIMP CAutoRect::OnPropertyChanged(IDispatch *AGraphic, long PropID, VARIANT *ValueOld, VARIANT *ValueNew)
  673. {
  674.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  675.  
  676.     // TODO: Add your implementation code here
  677.     HRESULT hRes = S_OK;
  678.  
  679.     return hRes;
  680. }
  681.  
  682. STDMETHODIMP CAutoRect::OnPropertyChanging(IDispatch *AGraphic, long PropID, VARIANT *ValueOld, VARIANT *ValueNew, VARIANT_BOOL* ret)
  683. {
  684.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  685.     HRESULT hRes = S_OK;
  686.  
  687.     // OK to change all of our properties, so just return TRUE.
  688.     *ret = TRUE;
  689.     return hRes;
  690. }
  691.  
  692. STDMETHODIMP CAutoRect::OnPropertyGet(IDispatch *AGraphic, long PropID)
  693. {
  694.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  695.     HRESULT hRes = S_OK;
  696.  
  697.     // No special recalculating of properties needed.
  698.     return hRes;
  699. }
  700.  
  701. STDMETHODIMP CAutoRect::Draw(IDispatch *AGraphic, IDispatch *AView, VARIANT *AMatrix, VARIANT_BOOL* ret)
  702. {
  703.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  704.     HRESULT hRes = E_FAIL;
  705.  
  706.     // We don't handle special drawing, so just return FALSE.
  707.     ret = FALSE;
  708.     return hRes;
  709. }
  710.  
  711. STDMETHODIMP CAutoRect::Regen(IDispatch *AGraphic)
  712. {
  713.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  714.     HRESULT hRes = E_FAIL;
  715.  
  716.     try
  717.     {
  718.         IGraphic* pIGraphic = NULL;
  719.         hRes = AGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic);
  720.         CHECK_HRESULT(hRes)
  721.  
  722.         long lockCount = 0;
  723.         if (SUCCEEDED(pIGraphic->RegenLock(&lockCount)))
  724.         {
  725.             if (lockCount == 0)
  726.             {
  727.                 Graphics* pGraphics = NULL;
  728.                 IGraphic* pChild = NULL;
  729.                 IVertex* pIVertex = NULL;
  730.                 if (SUCCEEDED(pIGraphic->get_Graphics(&pGraphics)))
  731.                 {
  732.                     COleVariant flags = (const long)GF_COSMETIC;
  733.                     pGraphics->Clear(&flags);
  734.  
  735.                     // Calculate height, width and radius of corners
  736.                         
  737.                     double px[4] = { 0.0 };
  738.                     double py[4] = { 0.0 };
  739.                     double pz[4] = { 0.0 };
  740.                     for (int i = 0; i < 4; ++i)
  741.                         GetVertexXYZ(pIGraphic, i, px[i], py[i], pz[i]);
  742.  
  743.                     BOOL bHandleMoved = !(fabs(px[2] - px[3]) < 0.000001 && 
  744.                         fabs(py[2] - py[3]) < 0.000001);
  745.  
  746.                     double w = fabs(px[1] - px[0]);
  747.                     double h = fabs(py[1] - py[0]);
  748.                     double r = (w < h) ? (w/2.0) : (h/2.0);
  749.                     
  750.                     double roundness;
  751.                     if (bHandleMoved)
  752.                     {
  753.                         if (r == 0.0)
  754.                             roundness = 0.0;
  755.                         else
  756.                         {
  757.                             roundness = fabs(px[2] - px[3]) * 100.0 / r;
  758.                             if (roundness > 100.0)
  759.                                 roundness = 100.0;
  760.                         }
  761.                         SetRoundness(pIGraphic, roundness);
  762.                     }
  763.                     else
  764.                     {
  765.                         roundness = GetRoundness(pIGraphic);
  766.                     }
  767.                     r = r * roundness / 100.0;                                        
  768.                         
  769.                     // Add child graphics
  770.                     // Make sure p[0] < p[1]
  771.                     double swap;
  772.                     if (px[0] > px[1])
  773.                     {
  774.                         swap = px[0];
  775.                         px[0] = px[1];
  776.                         px[1] = swap;
  777.                     }
  778.                     if (py[0] > py[1])
  779.                     {
  780.                         swap = py[0];
  781.                         py[0] = py[1];
  782.                         py[1] = swap;
  783.                     }
  784.  
  785.                     if (r == 0.0) 
  786.                     {
  787.                         // No rounded corners
  788.                         // All children are cosmetic
  789.                         if (SUCCEEDED(pGraphics->Add(
  790.                             &missing /*GraphicType*/,
  791.                             &missing /*RegenMethod*/,
  792.                             &t /*Inherit*/, 
  793.                             &missing /*Style*/,
  794.                             &missing /*Before*/,
  795.                             &missing /*After*/,                    
  796.                             &pChild)))
  797.                         {
  798.                             pChild->put_Cosmetic(TRUE);
  799.  
  800.                             COleVariant x, y;
  801.                             Vertices* pVerts = NULL;
  802.                             IVertex* pIVertex = NULL;
  803.                             if (SUCCEEDED(pChild->get_Vertices(&pVerts)))
  804.                             {
  805.                                 for (int i = 0; i < 4; ++i)
  806.                                 {
  807.                                     x = px[(i == 0 || i == 1) ? 0 : 1];
  808.                                     y = py[(i == 0 || i == 3) ? 0 : 1];
  809.                                     if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  810.                                         (i == 0) ? &f : &t /*penDown*/, 
  811.                                         &t /*selectable*/,
  812.                                         &t /*snappable*/,
  813.                                         &t /*editable*/, 
  814.                                         &t /*linkable*/,
  815.                                         &f /*calculated*/,
  816.                                         &missing /*before*/,
  817.                                         &missing /*after*/,
  818.                                         &pIVertex)))
  819.                                         pIVertex->Release();
  820.                                 }
  821.                                 if (SUCCEEDED(pVerts->AddClose(
  822.                                     &t /*penDown*/, 
  823.                                     &t /*selectable*/,
  824.                                     &t /*snappable*/,
  825.                                     &t /*editable*/, 
  826.                                     &t /*linkable*/,
  827.                                     &f /*calculated*/,
  828.                                     &pIVertex)))
  829.                                     pIVertex->Release();
  830.  
  831.                                 pVerts->Release();
  832.                             }
  833.                             pChild->Release();
  834.                         }
  835.                     }
  836.                     else
  837.                         {
  838.                             // Rounded corners
  839.                             // We'll make 4 line children and 4 arc children
  840.                             AddLineChild(pGraphics, px[0] + r, py[0],     px[1] - r, py[0]);
  841.                             AddArcChild (pGraphics, px[1] - r, py[0] + r, r, 1.5 * PI, 0.0);
  842.                             AddLineChild(pGraphics, px[1],     py[0] + r, px[1],     py[1] - r);
  843.                             AddArcChild (pGraphics, px[1] - r, py[1] - r, r, 0.0, 0.5 * PI);
  844.                             AddLineChild(pGraphics, px[1] - r, py[1],     px[0] + r, py[1]);
  845.                             AddArcChild (pGraphics, px[0] + r, py[1] - r, r, 0.5 * PI, PI);
  846.                             AddLineChild(pGraphics, px[0],     py[1] - r, px[0],     py[0] + r);
  847.                             AddArcChild (pGraphics, px[0] + r, py[0] + r, r, PI, 1.5 * PI);
  848.                         }
  849.                     pGraphics->Release();
  850.                 }
  851.             }
  852.             pIGraphic->RegenUnlock(&missing);
  853.         }
  854.         pIGraphic->Release();
  855.     }
  856.     catch (...)
  857.     {
  858.         TRACE_EXCEPTION("CAutoRect::Regen")
  859.         
  860.     }
  861.     return hRes;
  862. }
  863.  
  864. STDMETHODIMP CAutoRect::Initialize(IDispatch *ThisRegenMethod, VARIANT_BOOL* ret)
  865. {
  866.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  867.     HRESULT hRes = S_OK;
  868.     // TODO: Add your implementation code here
  869.     m_pRectPage = NULL;
  870.     *ret = TRUE;
  871.     return hRes;
  872. }
  873.  
  874.  
  875.  
  876.